<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>中国5A景区可视化</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/3.7.2/echarts.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="china.js"></script>
    <style>
        .map-wrap{width:100%;height:100vh;background-color:#EBEBEB;position:relative;display:flex;}
        .map-wrap #sideBar{width:33.33%;height:100%;position:relative;}
        .map-wrap #sideBar #subChart{width:100%;height:66%;margin-top:-10%;position: relative;}
        .map-wrap #sideBar #subMap{width:100%;height:50%;margin-top:-10%;position: relative;}
        .map-wrap #chart{width:66.66%;height:97%;margin-top:2%;position: relative;}
        .map-wrap #selector{position: absolute;left:36%;top:10%;width:10%;height:20%;background-color:transparent;z-index:1;}
        .map-wrap #selector div{margin-top: 5%;}
        .map-wrap #url{position: absolute;left:25%;top:52%;width:10%;height:20%;background-color:transparent;z-index:1;}
        .map-wrap #legend{position: absolute;left:28%;top:5%;width:5%;height:5%;background-color:transparent;z-index:1;}
        .map-wrap #enterGallery{position: absolute;right:3% ;top: 10%;height: 10%;background-color: transparent;z-index: 1;}
    </style>
</head>
<body>
    <div class="map-wrap">
        <div id="sideBar">
            <div id="subChart"></div>
            <div id="subMap"></div>
        </div>
        <div id="url"></div>
        <div id="chart"></div>
        <div id="selector">
            截止年份：<span id="show">2023</span><input type="range" id="ran" min="2006" max="2023" value="2023" onchange="applySelector()">
            <div>
                <label for="type">景点类型:</label>
                <select id="type">
                    <option value=2 selected>全部</option>
                    <option value=0>自然</option>
                    <option value=1>人文</option>
                </select>
            </div>
            <div>
                <label for="sortBy">排序指标:</label>
                <select id="sortBy">
                    <option value="销量" selected>热度</option>
                    <option value="评分">评分</option>
                    <option value="价格">价格</option>
                    <option value="交通">交通</option>
                    <option value="时间">时间</option>
                </select>
            </div>
            <div>
                <label for="sortOrder">排序方式:</label>
                <select id="sortOrder">
                    <option value="升序">升序</option>
                    <option value="降序" selected>降序</option>
                </select>
            </div>
            <div>
                <label for="selectCount">展示个数:</label>
                <select id="selectCount">
                    <option value="4">4</option>
                    <option value="6">6</option>
                    <option value="8">8</option>
                    <option value="10">10</option>
                    <option value="12" selected>12</option>
                    <option value="15">15</option>
                    <option value="20">20</option>
                    <option value="25">25</option>
                </select>
            </div>
            <div style="text-align: center;">
                <button onclick="applySelector()">确认筛选</button>
                <div></div>
                <button onclick="show_all()">展示全国</button>
            </div>
        </div>
        <div id="enterGallery">
            <button onclick="openGalleryPage()">静态可视化挖掘</button>
        </div>
        <div id="legend">
            <div style="display: flex; align-items: center;">
                <div style="background-color: rgba(55, 125, 34, 0.7); padding: 5px; width: 1%; height: 1%;"></div>
                <span style="margin-left: 5px;">自然</span>
            </div>
            <div style="display: flex; align-items: center;">
                <div style="background-color: rgba(50, 130, 246, 0.7); padding: 5px; width: 1%; height: 1%;"></div>
                <span style="margin-left: 5px;">人文</span>
            </div>
        </div>
    </div>

    <script type="text/javascript">
        function openGalleryPage() {
            window.open("gallery.html");
        }
    </script>

    
    <script type="text/javascript">
        function applySelector() {
            // Modify global variables based on the result
            var sortByCn = document.getElementById("sortBy").value;
            switch (sortByCn) {
                case "评分":
                    sortBy = "rating";
                    break;
                case "价格":
                    sortBy = "price";
                    break;
                case "销量":
                    sortBy = "sales";
                    break;
                case "交通":
                    sortBy = "transportation";
                    break;
                case "时间":
                    sortBy = "date";
                    break;
            }
            sortOrder = document.getElementById("sortOrder").value === "降序" ? 0 : 1;
            selectCount = document.getElementById("selectCount").value;
            typeFilter = document.getElementById("type").value;

            ran = document.getElementById("ran");
            document.getElementById('show').innerHTML = ran.value;
            year = ran.value;

            // Call showProvince() function
            tableData = filterAlldata();
            if (showall == 1) {
                show_all();
            }
            else {
                showGlobal();
                showProvince();
            }
        }
    </script>

    <script type="text/javascript">
        function filterAlldata() {
            filtereddata = tableData_all.filter(function(d) {
                return d.date <= year;
            });
            if (typeFilter == 0) {
                filtereddata = filtereddata.filter(function(d) {
                    return d.type == 0;
                });
            } else if (typeFilter == 1) {
                filtereddata = filtereddata.filter(function(d) {
                    return d.type == 1;
                });
            }
            return filtereddata;
        }
    </script>


    <script type="text/javascript">
        // Read the CSV file and store the table in the global variable
        function readCSVFile() {
            return d3.csv("./data.csv").then(function(data) {
                tableData_all = data.map(function(d) {
                    var province = d["省级行政区"];
                    if (province.startsWith("内蒙") || province.startsWith("黑龙")) {
                        province = province.substring(0, 3);
                    } else {
                        province = province.substring(0, 2);
                    }
                    var city = d["地级行政区"];
                    var attraction = d["景点名称"];
                    var rating = d["评分"];
                    var address = d["地址"];
                    var comment = d["评语"];
                    var price = d["价格"];
                    var sales = d["销量"];
                    var longitude = d["经度"];
                    var latitude = d["纬度"];
                    var transportation = d["交通"];
                    var type = d["人文1自然0"];
                    var date = parseInt(d['确立时间'].split('/')[0]);
                    var dateday = d['确立时间'];
                    var weburl = d['官方网站']
                    
                    return {
                        province: province,
                        city: city,
                        attraction: attraction,
                        rating: rating,
                        address: address,
                        comment: comment,
                        price: price,
                        sales: sales,
                        longitude: longitude,
                        latitude: latitude,
                        transportation: transportation,
                        type: type,
                        date: date,
                        dateday: dateday,
                        weburl:weburl
                    };
                });
                tableData = tableData_all
            });
        }
    </script>


    <script type="text/javascript">
        // Define a global function to filter and sort data
        function filterAndSortData(province, sortBy, sortOrder, selectCount) {
            // Filter data based on province
            if (province == "all") {
                var filteredData = tableData;
            } else {
                var filteredData = tableData.filter(function(d) {
                    return d.province === province;
                });
            }

            // If selectCount > filteredData.length, set selectCount = filteredData.length
            if (selectCount > filteredData.length) {
                selectCount = filteredData.length;
            }

            // Sort data based on sortBy and sortOrder
            filteredData.sort(function(a, b) {
                if (sortOrder === 0) {
                    return a[sortBy] - b[sortBy];
                } else {
                    return b[sortBy] - a[sortBy];
                }
            });

            // Select top selectCount attractions
            var selectedData = filteredData.slice(filteredData.length - selectCount, filteredData.length);

            // Extract attraction name and the specified indicator value
            var result = selectedData.map(function(d) {
                return {
                    attraction: d.attraction,
                    value: d[sortBy]
                };
            });
            return result;
        }
    </script>


    <script type="text/javascript">
        // Define a global function to get longitude and latitude of all attractions in a province
        // data = [
        // { name: 'Point A', value: [longitudeA, latitudeA] },
        // { name: 'Point B', value: [longitudeB, latitudeB] },
        // // Add more points as needed
        //  ];
        function getLongitudeAndLatitude(province) {
            var filteredData = tableData.filter(function(d) {
                return d.province === province;
            });

            var result = filteredData.map(function(d) {
                return {
                    name: d.attraction,
                    value: [d.longitude, d.latitude]
                };
            });
            return result;
        }
    </script>


    <script type="text/javascript">
        // Define a global function to get the number of attractions in each province
        // counts = {
        //     'provinceA': countA,
        //     'provinceB': countB,
        //     // Add more provincesEn as needed
        // };
        function getProvinceCounts(provincesEn) {
            var counts = {};
            provincesEn.forEach(function(province) {
                // if (typeFilter == 0) {
                //     var count = tableData.filter(function(data) {
                //         return data.province === province && data.type == 0;
                //     }).length;
                // }
                // else if (typeFilter == 1) {
                //     var count = tableData.filter(function(data) {
                //         return data.province === province && data.type == 1;
                //     }).length;
                // }
                // else {
                //     var count = tableData.filter(function(data) {
                //         return data.province === province;
                //     }).length;
                // }
                var count = tableData.filter(function(data) {
                    return data.province === province;
                }).length;
                counts[province] = count;
            });
            return counts;
        }
    </script>


    <script type="text/javascript">
        // Get information of a certain attraction
        // return a string
        // e.g. "xxx\n评语：xxx\n评分：xxx/1\n价格：xxx\n销量：xxx\n交通：xxx"
        function getAttractionInfo(attraction) {
            var filteredData = tableData.filter(function(d) {
                return d.attraction === attraction;
            });
            var result = "<p style=\"font-size:14px;white-space: pre-line;\" id=\"p1\">" +
                filteredData[0].attraction + "\n" +
                "评语：" + filteredData[0].comment + "\n" +
                "评分：" + filteredData[0].rating + "/1\n" +
                "价格：" + filteredData[0].price + "元\n" +
                "热度：" + filteredData[0].sales + "\n" +
                "交通：" + filteredData[0].transportation + "km\n"+ 
                "地址：" + filteredData[0].address + "\n" + 
                "确立时间：" + filteredData[0].dateday;
            return result;
        }
    </script>


    <script type="text/javascript">
        function drawBarChart(data) {
            var subChart = echarts.init(document.getElementById('subChart'));
            
            // range: [0, 1] for sortBy='rating'
            // range: [0, 500] for sortBy='price'
            // range: [0, 10000] for sortBy='sales'
            // range: [0, 300] for sortBy='transportation'
            var xmin = 0;
            values = data.map(function(d) {
                        return d.value;
                    })
            v_len = values.length
            // console.log(v_len)
            xmax = Math.max(...values) * 1.05
            xmax = Math.ceil(xmax)
            console.log(xmax)
            switch (sortBy) {
                case "rating":
                    var xmax = 1;
                    break;
                case "date":
                    xmin = 2006
                    var xmax = 2023;
                    break;
            }

            var optionSubChart = {
                tooltip: {
                    trigger: 'item', // Trigger tooltip on item (i.e., the bar in the bar chart)
                    position: function (point, params, dom, rect, size) {
                        // Set the tooltip position at the right and bottom of the mouse
                        return [point[0] + 10, point[1] + 10];
                    },
                    formatter: function(params) {
                        // Get the name of the attraction from the data point
                        var attraction = params.name;
                        // Use the getAttractionInfo function to get the info string
                        var info = getAttractionInfo(attraction);
                        // Return the info string to be displayed in the tooltip
                        return info;
                    }
                },
                yAxis: {
                    show: v_len > 30 ? false : true,
                    type: 'category',
                    position: 'right',
                    data: data.map(function(d) {
                        // console.log(d.attraction)
                        return d.attraction;
                    }),
                    axisLabel: {
                        z: 10
                    }
                },
                xAxis: {
                    type: 'value',
                    min: xmin,
                    max: xmax,
                    axisLabel:{
                        formatter:function(value){
                            return value+"";
                        }
                    }
                },
                grid: {
                    right: '50%', // Adjust the right margin as needed
                },
                series: [{
                    data: data.map(function(d) {
                        // console.log
                        return d.value;
                    }),
                    type: 'bar',
                    barWidth: 300/selectCount,
                    itemStyle: {
                        normal: {
                            color: function(params) {
                                type = tableData.filter(function(d) {
                                    return d.attraction == params.name;
                                })[0].type;
                                color = 'rgb(50, 130, 246, 0.7)'
                                if (type == 0) {
                                    color = 'rgb(55, 125, 34, 0.7)'
                                }
                                return color;
                            }
                        }
                    }
                }]
            };
            
            subChart.setOption(optionSubChart);
            return subChart;
        }
    </script>


    <script type="text/javascript">
        //展示对应的省
        function  showProvince() {
            showall = 0;
            // Need to use global variable province, sortBy, sortOrder, selectCount, provincesCn, provincesEn
            var provinceEn = 0;
            for(var i=0;i<provincesCn.length;i++){
                if(province == provincesCn[i]){
                    provinceEn = provincesEn[i];
                    break;
                }
            }
            if (provinceEn === 0) {
                console.warn('No data available for province ' + province);
                return; // Exit if no data available
            }

            var filteredData = filterAndSortData(province, sortBy, sortOrder, selectCount);
            var subChart = drawBarChart(filteredData);

            loadBdScript('$'+provinceEn+'JS','province/'+provinceEn+'.js',function(){
                subMap = initEcharts(provinceEn,province); 
                modifyChartOnClick(subChart, subMap);
            });
        }

        function loadBdScript(scriptId, url, callback) {
            var script = document.createElement("script")  
            script.type = "text/javascript";  
            if (script.readyState){  //IE  
                script.onreadystatechange = function(){  
                    if (script.readyState == "loaded" || script.readyState == "complete"){  
                        script.onreadystatechange = null;  
                        callback();  
                    }  
                };  
            } else {  //Others  
                script.onload = function(){  
                    callback();  
                };  
            }  
            script.src = url; 
            script.id = scriptId;
            document.getElementsByTagName("head")[0].appendChild(script); 
        };

        //加载个省市地图
        function initEcharts(subName, subText) {
            var child = echarts.init(document.getElementById('subMap'));
            
            var longitudeAndLatitude = getLongitudeAndLatitude(province);
            
            if (longitudeAndLatitude.length === 0) {
                console.error('No data available for scatter series');
                return; // Exit if no data available
            }
            
            // Ensure the series configuration is correctly set
            var optionSubMap = {
                tooltip: {
                    trigger: 'item', // Trigger tooltip on item (i.e., the bar in the bar chart)
                    position: function (point, params, dom, rect, size) {
                        // Set the tooltip position at the right and bottom of the mouse
                        return [point[0] + 10, point[1] + 10];
                    },
                    formatter: function(params) {
                        // Get the name of the attraction from the data point
                        var attraction = params.name;
                        // Use the getAttractionInfo function to get the info string
                        var info = getAttractionInfo(attraction);
                        // Return the info string to be displayed in the tooltip
                        return info;
                    }
                },
                series: [
                    {
                        type: 'map',
                        mapType: subText,
                        label: {
                            normal: {
                                show: false
                            },
                            emphasis: {
                                show: true
                            }
                        },
                        itemStyle: {
                            normal: {
                                show: true,
                                areaColor: "#FFFACD",
                                borderColor: "gray",
                                // borderColor: "#FCFCFC",
                                borderWidth: "1"
                            },
                            emphasis: {
                                show: true,
                                areaColor: "#C8A5DF",
                            }
                        },
                        tooltip: {
                            show: false
                        },
                    },
                    {
                        type: 'scatter',
                        coordinateSystem: 'geo',
                        data: longitudeAndLatitude,
                        itemStyle: {
                            normal: {
                                color: function(params) {
                                    type = tableData.filter(function(d) {
                                        return d.attraction == params.name;
                                    })[0].type;
                                    color = 'rgb(50, 130, 246, 0.7)'
                                    if (type == 0) {
                                        color = 'rgb(55, 125, 34, 0.7)'
                                    }
                                    return color;
                                }
                            }
                        },
                    }
                ],
                geo: {
                    map: subText // Ensure geo map type is set correctly
                }
            }

            child.setOption(optionSubMap);
            return child;
        }
    </script>


    <script type="text/javascript">
        function modifyChartOnClick(subChart, subMap) {
            subChart.on('click', function (params) {
                var selectedAttraction = params.name;
                weburl = tableData.filter(function(d) {
                    return d.attraction == selectedAttraction;
                })[0].weburl;
                if (weburl.length > 0) {
                    document.getElementById('url').innerHTML = "<p style=\"font-size:14px;white-space: pre-line;\" id=\"p1\">景区网站外部链接\n<a href=\"" + 
                        weburl + "\" target=\"_blank\" >" + selectedAttraction + "</a>";
                }
                else {
                    document.getElementById('url').innerHTML = '';
                }

                // Find the corresponding scatter point in subMap
                var scatterSeries = subMap.getOption().series.find(series => series.type === 'scatter');
                var scatterData = scatterSeries.data;
                var scatterIndex = scatterData.findIndex(point => point.name === selectedAttraction);

                // Change color of the selected scatter point to yellow
                scatterData.forEach((point, index) => {
                    type = tableData.filter(function(d) {
                        return d.attraction == point.name;
                    })[0].type;
                    select_color = 'rgb(4, 42, 255)'
                    color = 'rgb(50, 130, 246, 0.7)'
                    if (type == 0) {
                        select_color = 'rgb(90, 204, 55)'
                        color = 'rgb(55, 125, 34, 0.7)'
                    }
                    // console.log(color)
                    point.itemStyle = {
                        normal: {
                            borderColor: index === scatterIndex ? 'red' : 'none',
                            color: index === scatterIndex ? select_color : color
                        }
                    };
                });

                var optionSubMap = subMap.getOption();
                optionSubMap.series[1].data = scatterData;
                subMap.setOption(optionSubMap);
                var barName = subChart.getOption().yAxis[0].data;
                var barIndex = barName.findIndex(attraction => attraction === selectedAttraction);

                // Change color of the selected bar to purple
                var newItemStyle = subChart.getOption().series[0].itemStyle;
                newItemStyle.normal.color = function(params) {
                    type = tableData.filter(function(d) {
                        return d.attraction == params.name;
                    })[0].type;
                    select_color = 'rgb(4, 42, 255)'
                    color = 'rgb(50, 130, 246, 0.7)'
                    if (type == 0) {
                        select_color = 'rgb(90, 204, 55)'
                        color = 'rgb(55, 125, 34, 0.7)'
                    }
                    return params.dataIndex === barIndex ? select_color : color;
                };

                var optionSubChart = subChart.getOption();
                optionSubChart.series[0].itemStyle = newItemStyle;
                subChart.setOption(optionSubChart);
            });

            subMap.on('click', function (params) {
                var selectedAttraction = params.data.name;
                weburl = tableData.filter(function(d) {
                    return d.attraction == selectedAttraction;
                })[0].weburl;
                if (weburl.length > 0) {
                    document.getElementById('url').innerHTML = "<p style=\"font-size:14px;white-space: pre-line;\" id=\"p1\">景区网站外部链接\n<a href=\"" + 
                        weburl + "\" target=\"_blank\" >" + selectedAttraction + "</a>";
                }
                else {
                    document.getElementById('url').innerHTML = '';
                }
                // Find the corresponding scatter point in subMap
                var scatterSeries = subMap.getOption().series.find(series => series.type === 'scatter');
                var scatterData = scatterSeries.data;
                var scatterIndex = scatterData.findIndex(point => point.name === selectedAttraction);

                // Change color of the selected scatter point to yellow
                scatterData.forEach((point, index) => {
                    type = tableData.filter(function(d) {
                        return d.attraction == point.name;
                    })[0].type;
                    select_color = 'rgb(4, 42, 255)'
                    color = 'rgb(50, 130, 246, 0.7)'
                    if (type == 0) {
                        select_color = 'rgb(90, 204, 55)'
                        color = 'rgb(55, 125, 34, 0.7)'
                    }
                    point.itemStyle = {
                        normal: {
                            borderColor: index === scatterIndex ? 'red' : 'none',
                            color: index === scatterIndex ? select_color : color
                        }
                    };
                });

                var optionSubMap = subMap.getOption();
                optionSubMap.series[1].data = scatterData;
                subMap.setOption(optionSubMap);
                var barName = subChart.getOption().yAxis[0].data;
                var barIndex = barName.findIndex(attraction => attraction === selectedAttraction);

                // Change color of the selected bar to purple
                var newItemStyle = subChart.getOption().series[0].itemStyle;
                newItemStyle.normal.color = function(params) {
                    type = tableData.filter(function(d) {
                        return d.attraction == params.name;
                    })[0].type;
                    select_color = 'rgb(4, 42, 255)'
                    color = 'rgb(50, 130, 246, 0.7)'
                    if (type == 0) {
                        select_color = 'rgb(90, 204, 55)'
                        color = 'rgb(55, 125, 34, 0.7)'
                    }
                    return params.dataIndex === barIndex ? select_color : color;
                };

                var optionSubChart = subChart.getOption();
                optionSubChart.series[0].itemStyle = newItemStyle;
                subChart.setOption(optionSubChart);
            });
        }
    </script>


    <script type="text/javascript">
        function showGlobal(){
            var provinceCounts = getProvinceCounts(provincesCn);
            data = [];

            for (i=0; i<provincesEn.length; i++) {
                data.push({
                    name: provincesCn[i],
                    value: provinceCounts[provincesCn[i]]
                });
            }

            //指定图标的配置项和数据
            var option ={
                series : [
                {
                    name: '网点个数',
                    //series[i]-map:系列列表。每个系列通过 type 决定自己的图表类型,此处是地图类型
                    type: 'map', 
                    //这里是'china',及因为js中注册的名字，如果是上海市，则该出需provinceEn 指的是'shanghai'
                    mapType: 'china',
                    data:data,
                    textStyle:{
                        align:"center",
                        baseline:"middle"
                    },
                    
                    //地图区域的多边形 图形样式，有 normal 和 emphasis 两个状态
                    itemStyle: {
                    //normal 是图形在默认状态下的样式；
                        normal: {
                            show: true,
                            borderColor:"#FCFCFC",
                            borderWidth:"1"
                        },
                        //emphasis 是图形在高亮状态下的样式，比如在鼠标悬浮或者图例联动高亮时。
                        emphasis: {
                            show: true,
                        }
                    },
                    //图形上的文本标签，可用于说明图形的一些数据信息
                    label: {
                        normal: {
                            show: true,
                            formatter: function(params) {
                                return params.name + '\n' + provinceCounts[params.name];
                            }
                        },
                        emphasis: {
                            show: true
                        }
                    },
                }],
                title : {
                    text: '中国5A景区可视化地图',
                    left: 'center',
                    textStyle: {
                        fontSize: 36
                    }
                } ,
                visualMap: {
                    min: 0,
                    max: 26,
                    left: 'left',
                    top: 'bottom',
                    text: ['5A景区个数'],
                    inRange: {
                        color: ['#FFFFFF', 'rgba(52.5, 127.5, 140, 1)'] // White to deep red
                    },
                }
            };

            //使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);

            myChart.on('click', function (param) {
                document.getElementById('url').innerHTML = '';
                province = param.name;
                //遍历取到provincesCn 中的下标  去拿到对应的省js
                showProvince();         
            });
        }
    </script>

    <script type="text/javascript">
        function show_all() {
            showall = 1;
            if (subMap != 0) {
                subMap.clear();
            }
            showGlobal();
            // if (selectCount > 25) {
            //     selectCount = 25;
            // }
            var filteredData = filterAndSortData('all', sortBy, sortOrder, selectCount);
            drawBarChart(filteredData);
        }
    </script>



	<script type="text/javascript">
        
		var myChart = echarts.init(document.getElementById('chart'));
        var province = 0;
        var sortBy = "sales";
        var sortOrder = 0;
        var selectCount = 12;
        var tableData_all;
        var tableData;
        var typeFilter = 2;
        var year = 2023;
        var showall = 1;
        var subMap = 0;

        //定义全国省份的数组
        var provincesEn = ['shanghai', 'hebei','shanxi','neimenggu','liaoning','jilin','heilongjiang','jiangsu','zhejiang','anhui','fujian','jiangxi','shandong','henan','hubei','hunan','guangdong','guangxi','hainan','sichuan','guizhou','yunnan','xizang','shanxi1','gansu','qinghai','ningxia','xinjiang', 'beijing', 'tianjin', 'chongqing', 'xianggang', 'aomen','taiwan'];
        var provincesCn = ['上海', '河北', '山西', '内蒙古', '辽宁', '吉林','黑龙江',  '江苏', '浙江', '安徽', '福建', '江西', '山东','河南', '湖北', '湖南', '广东', '广西', '海南', '四川', '贵州', '云南', '西藏', '陕西', '甘肃', '青海', '宁夏', '新疆', '北京', '天津', '重庆', '香港', '澳门','台湾'];

        readCSVFile().then(show_all);
	</script>

</body>
</html>